﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UMLTouch.Core;
using UMLTouch.Core.Entities;
using UMLTouch.DomainRecognition.SegmentationAlgorithms;
using System.Threading;
using System.Collections.ObjectModel;
using UMLTouch.DomainRecognition.ShapeRecognition;
using UMLTouch.Core.UI;

namespace UMLTouch.DomainRecognition.Engines
{
    public class RecognitionEngine : AbstractEngine<Stroke,IDiagramItem>,IEngineInput<IDiagramItem>
    {

        public delegate void RecognizedItem(IDiagramItem recognizedItem);
        public event RecognizedItem OnRecognizedItem;

        
        AbstractEngine<SegmentedStroke, Shape> _shaRec;
        AbstractEngine<Stroke, SegmentedStroke> _segRec;
        AbstractEngine<Shape, IDiagramItem> _itRec;
      

        public AbstractEngine<SegmentedStroke, Shape> ShapeRecognitionEngine
        {
            get { return _shaRec; }
            set { _shaRec = value; }
        }
        public AbstractEngine<Stroke, SegmentedStroke> SegmentationEngine
        {
            get { return _segRec; }
            set { _segRec = value; }
        }
        public AbstractEngine<Shape, IDiagramItem> ItemRecognitionEngine
        {
            get { return _itRec; }
            set { _itRec = value; }
        }



        protected RecognitionEngine()
        {

        }


        public RecognitionEngine(ShapeRecognizer ShapeRecognizer)
            :this(ShapeRecognizer,new PersonnalAlgorithm())
        {
           
        }


        public RecognitionEngine(ShapeRecognizer ShapeRecognizer,ISegmentationAlgorithm segmentationAlgorithm)
        {
            _segRec = new SegmentationEngine(segmentationAlgorithm);
            _shaRec = new ShapeRecognitionEngine(ShapeRecognizer);
            _itRec = new ItemRecognitionEngine();

            _segRec.AddNextEngine(_shaRec);
            _shaRec.AddNextEngine(_itRec);
            _itRec.AddNextEngine(this);
        }


       

        public override void SpecificRecognition(Stroke t)
        {
            _segRec.InputItem(t);
        }

        public override void Dispose()
        {

            base.Dispose();
            _segRec.Dispose();
            _shaRec.Dispose();
            _segRec.Dispose();
        }

        protected void RaiseRecognizedItem(IDiagramItem item)
        {
            if (OnRecognizedItem.GetInvocationList().Count() > 0 && item != null) 
            {
                OnRecognizedItem(item);
            }
        }

        public override void PushOutput(IDiagramItem output)
        {
            base.PushOutput(output);
        }


        public void InputItem(IDiagramItem entity)
        {
            RaiseRecognizedItem(entity);
        }

    }
}
